package com.bawei.product.service.impl;

import com.bawei.product.service.TestAsyncService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.concurrent.CompletableFuture;

@Service
@Slf4j

public class TestAsyncServiceImpl  implements TestAsyncService {
    @SneakyThrows
    @Override
    public void thenRunAsync() {
        long startTime = System.currentTimeMillis();
            CompletableFuture<Integer> cf0 = CompletableFuture.completedFuture(1);
        CompletableFuture<Integer> cf1 = cf0.thenApplyAsync(result -> testA());
        CompletableFuture<Void> cf2 = cf0.thenRunAsync(() -> {
           testB();
        });
        CompletableFuture<Void> cf3 = cf0.thenRunAsync(() -> {
            testC();
        });
        // 使用allOf等待所有任务完成
        CompletableFuture<Void> allOf = CompletableFuture.allOf(cf1, cf2, cf3);
        allOf.join(); // 等待所有任务完成

        System.out.println("cf1结果->" + cf1.get());
        System.out.println("cf2结果->" + cf2.get());
        System.out.println("cf3结果->" + cf3.get());
        System.out.printf("耗时：" + (System.currentTimeMillis() - startTime));
    }




    /**
     * thenAccept子任务和父任务公用同一个线程
     */
    @SneakyThrows
    @Override
    public void thenRunAsync2() {
       /* testA();
        testB();
        testC();*/

        CompletableFuture<Integer> cf0 = CompletableFuture.completedFuture(1);


        CompletableFuture<Integer> cf1 = cf0.thenApplyAsync(result -> testA());
        CompletableFuture<Void> cf2 = cf0.thenRunAsync(() -> {
            testB();
        });

        CompletableFuture<Void> cf3 = cf0.thenRunAsync(() -> {
            testC();
        });
        //等待任务1执行完成
        System.out.println("cf1结果->" + cf1.get());
        //等待任务2执行完成
        System.out.println("cf2结果->" + cf2.get());
    }

    private void test0() {

    }

    private Integer testA() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return 1;
    }
    private void testB() {
        try {
            Thread.sleep(1200);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
    private void testC() {
        try {
            Thread.sleep(1400);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}
